gawk 프로그램은 데이터를 조작하는 고급 프로그램을 작성할 수 있는 기능을 제공하는 제대로된 프로그래밍 언어이다.
gawk's variables- 내장 변수
- 사용자 정의 변수
내장 변수gawk는 프로그램 데이터의 특정한 특징을 정의한는데 내장 변수를 사용한다.
- 필드와 레코드 분리 변수
데이터 레코드 안에서 데이터 필드의 위치를 참고해서 사용할 수 있다.($1, $2, ...)
데이터 필드를 구분하는 '필드 구분자'는 default로 빈 칸이나 탭과 같은 화이트스페이스 문자를 사용한다.
-F 커맨드라인 매개변수나, 내장 변수 FS를 이용해서 변경
FIELDWIDTHS: 각 데이터 필드의 정확한 폭(칸의 수)를 정의한 숫자의 목록으로 빈칸으로 구분
FS: 입력 필드 구분자
RS: 입력 레코드 구분자
OFS: 출력 필드 구분자
ORS: 출력 레코드 구분
필드 구분자
col=5
row=4
i=1
j=1
string=""
while [ $i -le $row ]; do
while [ $j -ne $col ]; do
string=$string"data"$i$j","
j=$[ $j + 1 ]
done
string=$string"data"$i$col"\n"
i=$[ $i + 1 ]
j=1
done
string=${string:0:-2}
echo -e $string > data.txt
gawk 'BEGIN{FS=","}{print $1,$2,$3}' data.txt
gawk 'BEGIN{FS=","; OFS="--"}{print $1,$2,$3}' data.txt
gawk 'BEGIN{FS=","; OFS="<--->"}{print $1,$2,$3}' data.txt
gawk 'BEGIN{FIELDWIDTHS="7 7 6"}{print $1,$2,$3}' data.txt
rm data.txt
레코드 구분자
echo 'Railey Mullen
123 Main Street
Chicago, IL 60601
(312)555-1234' > data.txt
gawk 'BEGIN{FS="\n"; RS=""} {print $1,$4}' data.txt
rm data.txt
- 데이터 변수ARGC: 커멘드 라인 매개변수
ARGIND: 현재 ARGV 인덱스
ARGV
CONVFMT: 번호 변환 포맷 default; %.6g
ENVIRON: 현재 쉘 환경 변수와 그 값의 연관 배열
ERRNO: 시스템 오류
FILENAME: gawk 입력에 사용되는 파일 이름
FNR: 데이터 파일의 현재 레코드 번호
IGNORECASE: 0이 아닌 값으로 설정 시, 대소문자 구분 무시
NF: 데이터 필드의 전체 개수
NR: 처리된 입력 레코드 수
OFMT: 아웃 풋 포맷 default; %.6g
RLENGTH: match 함수에서 일치하는 부속 문자열 길이
RSTART: match 함수에서 일치하는 부속 문자열의 시작 인덱스
gawk의 매개변수는 프로그램 스크립트를 포함하지 않음
=> ARGV[0]은 명령, ARGV[1]는 첫번째 매개변수
echo -e '1 2 3\n4 5 6\n7 8 9' > data.txt
gawk 'BEGIN{print ARGC, ARGV[1]}' data.txt
gawk '
BEGIN{
print ENVIRON["HOME"]
print ENVIRON["PATH"]
}'
gawk 'BEGIN{FS=":"; OFS=":"} {print $1,NF}' /etc/passwd
gawk 'BEGIN{FS=","} {print $1, "FNR="FNR, "NR="NR}' data.txt data.txt
rm data.txt
사용자 정의 변수- 커맨드 라인에서 사용자 정의 변수 할당
gawk '
BEGIN{
variable="This is the test"
print variable
}'
gawk '
BEGIN{
x=4; x=x*2+3; print x
}'
- 스크립트에서 사용자 정의 변수 할당
echo -e 'data11,data12,data13\ndata21,data22,data23' > data.txt
echo 'BEGIN{FS=","} {print $n}' > script.gawk
gawk -f script.gawk n=1 data.txt
gawk -f script.gawk n=2 data.txt
gawk -f script.gawk n=3 data.txt
rm data.txt script.gawk
일반적으로 BEGIN 영역에서는 매개변수로 설정한 값을 사용할 수 없음매개변수 앞에 -v 옵션을 사용해서 BEGIN에 변수를 설정하고 사용할 있다.
(단, -v 커맨드라인 매개변수는 커맨드라인에서 스크립트 코드 앞에 와야 함)
echo -e 'data11,data12,data13\ndata21,data22,data23' > data.txt
echo 'BEGIN{print "starting value:", n; FS=","} {print $n}' > script.gawk
gawk -v n=3 -f script.gawk data.txt
배열(연관 배열)일반 배열과 달리 연관 배열은 텍스트가 배열의 인덱스로 사용될 수 있음(해시 맵과 동일; 인덱스 문자열은 유일해야 함)
var[index]]=element
gawk 'BEGIN{
capital["Illinois"]="Sprintfield"
capital["Indiana"]="Indianapolis"
capital["Ohio"]="Columbus"
print capital["Illinois"]
}'
- 배열 변수를 이용한 for
for (var in array)
{
statements
}
매번 for 마다 var에 array의 인덱스 값이 지정
gawk 'BEGIN{
var["a"]=1
var["b"]=2
var["c"]=3
var["d"]=4
var["e"]=5
for ( ind in var )
{
print "Index:",ind," - Value:",var[ind]
}
}'
인덱스 값이 특정한 순서를 보장하지는 않음
(unordered_map)
- 배열 변수 제거delete array[index]
gawk 'BEGIN{
var["a"]=1
var["g"]=2
for( ind in var )
{
print "Index:",ind,"-Value:"var[ind]
}
delete var["g"]
print "--"
for ( ind in var )
{
print "Index:",ind,"-Value:"var[ind]
}
}'
패턴(Pattern)- 정규 표현식
BRE+ERE
정규 표현식은 해당 매칭을 사용하는 중괄호 앞에 /regEpr/ 작성
gawk 'BEGIN{FS=","} /11/{print $1}' data.txt
필드 구분자를 포함하여 모든 데이터 필드에 대해서 정규표현식을 대조
- 대조 연산자$# ~ 매칭을 #번째 데이터 필드로 제한
$# !~ 매칭을 #번째 데이터 필드로 제한하고, 부정형에 대해서 출력(매칭하지 않는 데이터 출력)
대조 연산자를 사용해서 레코드에서 특정 데이터 필드로 정규표현식을 제한
gawk 'BEGIN{
FS=","}
$2 ~ /^data2/{print $0}' data.txt
gawk -F: '$1 ~ /csian/{print $1, $NF}' /etc/passwd
gawk -F: '$1 !~ /csian/{print $1, $NF}' /etc/passwd
gawk -F: '$4<=500 {print $1}' /etc/passwd
구조적 명령- if
if (condition)
statement1
if (condition) statement1
if (condition)
{
statement1
} else
{
statement2
}
if (condition) statement1; else statement2
gawk -F: '{if ($4 > 500) print $1}' /etc/passwd
gawk -F: '{if ($4>500) print "user id:", $1; else print "system id:", $1}' /etc/passwd
- whilewhile (condition)
{
statement1
}
break, continue 사용 가능
echo -e "130 120 135\n160 113 140\n145 170 215" >data.txt
gawk '{
total=0
i=1
while(i<4)
{
total+=$i
i++
}
avg=total/3
print "Average:",avg
}' data.txt
rm data.txt
- do-whiledo
{
statement1
} while (condition)
- for(C type for 문과 유사)for (variable assignment; condition; iteration process)
echo -e "130 120 135\n160 113 140\n145 170 215" >data.txt
gawk '{
total=0
for(i=1; i<4; ++i){
total+=$i
}
avg=total/3
print "Average:",avg
}' data.txt
rm data.txt
서식화된 출력printf "string format",var1,var2,...
string format: %[modifier]control-letter
c: ASCII 문자
d: 정수
i: 정수(d와 동일)
e: 과학적 표기법
f: 부동 소수점
g: 과학적 표기법 | 부동 소수점 중 짧은 쪽으로 출력
o: 8진수
s: 텍스트 문자열
x: 16진수
X: 16진수(A-F까지 대문자 출력)
폭 지정: 출력이 지정된 폭보다 짧을 경우 오른쪽 정렬하고 빈칸으로 채움
자릿수: 소수점 이하에 표시할 숫자 수
-(뺴기 부호): 폭 지정 시, 오른쪽 정렬이 아닌 왼쪽 정렬 사용
print 문을 사용할 때 출력을 제어할 수 있는 것은 출력 필드 구분자를 제어하는 것 밖에 없다.
C와 유사한 printf를 사용하면, 서식(format)에 맞게 출력문을 제어할 수 있다.
printf는 print와 달리 줄바꿈(\n)을 포함하지 않는다.
echo 'Riley Mullen (312)555-1234
Frank Williams (317)555-9876
Haley Snell (313)555-4938' > data.txt
gawk 'BEGIN{FS=" "; RS="\n"} {printf "%16s %s\n", $1, $3} END{printf "\n"}' data.txt
rm data.txt
내장 함수(수학, 문자열, 시간 기능 등)- 수학
atan2(x,y): 아크탄젠트(x, y는 라디안)
cos(x)
exp(x)
int(x): 정수값으로 변경(0에 가까운 값으로 내림)
log(x)
rand(): [0-1)의 무작위 부동 소수점 값
sin(x)
sqrt(x)
srand(x): random seed 지정
and(v1, v2): v1, v2에 대한 비트 AND
compl(val): val에 대한 비트 단위 보수 계산
lshift(val, count): val에 대한 count 만큼 left shift
or(v1, v2): v1, v2에 대한 비트 OR
rshift(val, count)
xor(v1, v2): v1, v2에 대한 비트 XOR
- 문자열 함수asort(s[,d]): 배열의 데이터값에 대한 정렬(인덱스 값은 새 정렬 순서의 일련번호로 대체됨)
배열 d 지정시 정렬된 새로운 배열을 d에 저장
aorti(s[,d]): 배열의 인덱스값에 대한 정렬(결과 얻은 배열은 인덱스 값을 데이터 요소 값으로 가지고 일련번호가 정렬 순서인 인덱스)
gensub(r,s,h[,t])
gsub(r,s[,t])
index(s,t)
length([s])
match(s,r[,a])
split(s,a[,r])
sprintf(format,variables)
sub(r,s[,t])
tolewer(s)
toupper(s)
- 시간 함수mktime(datespec): YYYY MM DD HH MM SS [DST] 형식으로 지정된 시간 값을 타임스탬프 값으로 변경
strftime(format[,timestamp]):
현재 시간의 날짜 타임 스탬프, 또는 제공되는 타임스탬프를 date() 쉘 함수 형식을 사용하여 형식화된 시간과 날짜 형식 생성
systime(): 현재 시간에 대한 타임 스탬프
gawk 'BEGIN{
date=systime()
day=strftime("%A, %B, %d, %Y", date)
print day
}'
사용자 함수 정의function name([variables])
{
statements
}
return문 사용 가능
gawk '
function myPrint()
{
printf "%-16s - %s\n", $1, $4
}
BEGIN{FS="\n"; RS=""}
{myPrint()}
' data.txt
gawk 함수를 모아둔 library를 만들고
gawk -f funclib.gawk -f script.gawk data.txt 를 통해 사용 가능